package unwdmi.util;

import java.util.Queue;
import java.util.Set;

import unwdmi.cache.Cache;
import unwdmi.dto.MeasurementDTO;
/**
 * The validator is used to validate Measurements Objects
 * @author Stephan E G Veenstra
 *
 */
public class Validator {

	private Cache cache;
	
	public Validator() {
		this.cache = new Cache(30);
	}
	/**
	 * Validate a Measurement object and return it fixed
	 * @param measurement
	 * @return
	 */
	public MeasurementDTO validate(MeasurementDTO measurement){
		
//		System.out.println(measurement.getJSONString());
		
		cache.addMeasurements(measurement);
		
		// TODO VALIDATE temp!
		
		double temp = measurement.getTEMP();
		double highest = getHighestTemp(measurement.getSTN());
		double lowest = getLowestTemp(measurement.getSTN());
		double diff = highest-lowest;
		double max = cache.getMeasurements(measurement.getSTN()).peek().getTEMP() + diff/5;
		double min = cache.getMeasurements(measurement.getSTN()).peek().getTEMP() - diff/5;
		if(temp > max)
			measurement.setTEMP(max);
		else if(temp < min)
			measurement.setTEMP(min);
		
		if(measurement.getDEWP() == null){
			System.out.println("DEWP corrected from " + measurement.getDEWP() + " -> " + cache.getMeasurements(measurement.getSTN()).peek().getDEWP());
			measurement.setDEWP(cache.getMeasurements(measurement.getSTN()).peek().getDEWP());
		}
		if(measurement.getSTP() == null){
			measurement.setSTP(cache.getMeasurements(measurement.getSTN()).peek().getSTP());
		}
		if(measurement.getSLP() == null){
			measurement.setSLP(cache.getMeasurements(measurement.getSTN()).peek().getSLP());
		}
		if(measurement.getVISIB() == null){
			measurement.setVISIB(cache.getMeasurements(measurement.getSTN()).peek().getVISIB());
		}
		if(measurement.getWDSP() == null){
			measurement.setWDSP(cache.getMeasurements(measurement.getSTN()).peek().getWDSP());
		}
		if(measurement.getPRCP() == null){
			measurement.setPRCP(cache.getMeasurements(measurement.getSTN()).peek().getPRCP());
		}
		if(measurement.getSNDP() == null){
			measurement.setSNDP(cache.getMeasurements(measurement.getSTN()).peek().getSNDP());
		}
		if(measurement.getFRSHTT() == null){
			System.out.println("<<!---!>>");
			measurement.setFRSHTT(cache.getMeasurements(measurement.getSTN()).peek().getFRSHTT());
		}
		if(measurement.getCLDC() == null){
			measurement.setCLDC(cache.getMeasurements(measurement.getSTN()).peek().getCLDC());
		}
		if(measurement.getWNDDIR() == null){
			measurement.setWNDDIR(cache.getMeasurements(measurement.getSTN()).peek().getWNDDIR());
		}
		return measurement;
	}
	
	private Double getLowestTemp(int station) {
		Queue<MeasurementDTO> m = cache.getMeasurements(station);
		if(m == null)
			return null;
		else{
			Double lowest = null;
			for(MeasurementDTO dto : m){
				if(lowest == null)
					lowest = dto.getTEMP();
				else if(lowest > dto.getTEMP())
					lowest = dto.getTEMP();
			}
			return lowest;
		}
	}
	private Double getHighestTemp(int station) {
		Queue<MeasurementDTO> m = cache.getMeasurements(station);
		if(m == null)
			return null;
		else{
			Double highest = null;
			for(MeasurementDTO dto : m){
				if(highest == null)
					highest = dto.getTEMP();
				else if(highest < dto.getTEMP())
					highest = dto.getTEMP();
			}
			return highest;
		}
	}
	/**
	 * 
	 */
	private double getExtrapolationBySet(double[] set) {
		int i = 1;
		for(; i < set.length-1; i++) {
			set[i] = (set[i] - set[i-1]) + set[i]; 
			System.out.println(set[i]);
		};
		return set[i];
	};
	
}
